﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Portal.Data.Entity;

namespace Portal.Data.Crawler
{
    public class BlogTruyen
    {
        #region ctor
        private static readonly HtmlParser _parser = new HtmlParser();
        private static class Singleton
        {
            public static readonly BlogTruyen Instance = new BlogTruyen();
        }
        public static BlogTruyen Instance
        {
            get
            {
                return Singleton.Instance;
            }
        }
        #endregion

        #region Config

        private const string DomainLink = "http://blogtruyen.com";
        const string OpenTag = "<section id=\"main-left\"";
        const string CloseTag = "</section>";

        const string OpenListChap = "<div class=\"list-wrap\" id=\"list-chapters";
        const string CloseListChap = "</div>";
        #endregion

        public int GetNewChaps(Book b, out string errorMessage)
        {
            errorMessage = "";
            int newcount = 0;
            var sources = Common.GetHtmlSources(b.CrawlUrl);
            if (sources.Length > 0)
            {
                sources = _parser.Replace(sources, HtmlParser.Patterns.BREAK, " ");
                var ss = _parser.GetContentInNode(sources, OpenTag, CloseTag);
                if (ss.Count > 0)
                {
                    var s = ss[0];
                    try
                    {
                        var ccl = new CommonCrawler();

                        //get list older chapter
                        var allExisted = Content.FindByBook(b.ID).Select(x => x.CrawlUrl).ToList();

                        var blocklistchap = _parser.GetContentInNode(s, OpenListChap, CloseListChap);
                        if (blocklistchap.Count > 0)
                        {
                            var allChapFromSource = _parser.GetBetweenTag(blocklistchap[0], "p");
                            //int totalFromSource = allChapFromSource.Count;
                            int nextChapter = allExisted.Count;
                            var newLastChapId = 0;
                            for (int i = allChapFromSource.Count-1; i >=0; i--)
                            {
                                nextChapter++;
                                var text = HttpUtility.HtmlDecode(allChapFromSource[i].Value);
                                var chap = new Content { Book_ID = b.ID, Chapter = nextChapter, SafeNameBook = b.SafeName };
                                var tagAs = _parser.GetBetweenTag(text, "a");
                                if (tagAs.Count > 0)
                                {
                                    var urls = _parser.GetProperty(tagAs[0].Value, "href");
                                    if (urls.Count > 0)
                                    {
                                        var crawlUrl = urls[0].Groups[4].Value.Trim();
                                        chap.CrawlUrl = Common.FillAbsoluteLink(DomainLink, crawlUrl);
                                    }
                                    chap.Title = _parser.RemoveAllTag(tagAs[0].Value).Trim();
                                }
                                if (!allExisted.Contains(chap.CrawlUrl))
                                {
                                    allExisted.Add(chap.CrawlUrl);//add into existed

                                    chap.BodyTemp = ccl.GetChapBody(chap.CrawlUrl, out errorMessage);
                                    chap.Broken = chap.BodyTemp.Length == 0;
                                    chap.Save();
                                    newLastChapId = chap.Content_ID;

                                    newcount++;
                                }

                            }

                            //update last chapId for book
                            if (newLastChapId > 0)
                                b.ChangeLastChap(newLastChapId, allExisted.Count);
                        }
                        else
                        {
                            errorMessage = b.CrawlUrl + ": get null list chap";
                        }
                    }
                    catch (Exception ex)
                    {
                        errorMessage = ex.Message;
                        return newcount;
                    }
                }
            }
            else
            {
                errorMessage = b.CrawlUrl + ": get null data";
            }
            return newcount;
        }
    }
}

